package com.dky.satell.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.dky.satell.dto.ResultDto;
import com.dky.satell.entity.OfflineFile;
import com.dky.satell.entity.xml.Field;
import com.dky.satell.entity.xml.Fields;
import com.dky.satell.entity.xml.FileSchema;
import com.dky.satell.mapper.OfflineFileMapper;
import com.dky.satell.thirdParty.label.LabelTemplate;
import com.dky.satell.util.MD5Utils;
import com.dky.satell.util.ServiceUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.dky.satell.kafka.model.OfflineFileWarpper;
import com.dky.satell.kafka.producer.KafkaProducer;
import com.dky.satell.service.OfflineFileService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.*;
import java.util.Date;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author mark
 * @since 2021-04-25
 */
@Slf4j
@Service
public class OfflineFileServiceImpl extends ServiceImpl<OfflineFileMapper, OfflineFile> implements OfflineFileService {

    /**
     * 上传本地路径
     */
    @Value("${file.uploadPath}")
    private String uploadPath;

    /**
     * 上传目标路径
     */
    @Value("${proxy.file.send}")
    private String proxyFileSend;

    @Resource
    private OfflineFileMapper offlineFileMapper;

    @Resource
    private KafkaProducer kafkaProducer;

    @Autowired
    private LabelTemplate labelTemplate;

    @Override
    public ResultDto insert(MultipartFile file, OfflineFile offlineFile) {
        try {
            offlineFile.setSource(1);
            File schemaFile = this.generateMeta(offlineFile);
            offlineFile.setProxyFileName(ServiceUtil.buildProxyFileName(offlineFile.getFileName(), schemaFile.getName()));
            return this.upload(file.getInputStream(), offlineFile, schemaFile);
        } catch (IOException e) {
            log.error("本地生成文件失败!", e);
            return ResultDto.fail("uploading failed");
        }
    }

    public ResultDto insert(File file, OfflineFile offlineFile, File schemaFile) {
        try {
            offlineFile.setSource(2);
            return this.upload(new FileInputStream(file), offlineFile, schemaFile);
        } catch (IOException e) {
            log.error("本地生成文件失败!", e);
            return ResultDto.fail("uploading failed");
        }
    }

    private ResultDto upload(InputStream inputStream, OfflineFile offlineFile, File schemaFile) {
        String proxyFileName= offlineFile.getProxyFileName();
        String filePath = uploadPath + proxyFileName;
        File f = new File(filePath);
        try {
            FileUtils.copyInputStreamToFile(inputStream,f);
        } catch (IOException e) {
            log.error("本地生成文件失败!",e);
            return ResultDto.fail("uploading failed");
        }
        Date date = new Date();
        offlineFile.setFileSize(f.length());
        offlineFile.setSign(MD5Utils.getFileMD5String(f));
        offlineFile.setCreateTime(date);
        this.save(offlineFile);
        // 发送文件到跨网代理
        ServiceUtil.sendToProxy(proxyFileName, f.length(), offlineFile.getRegion(), proxyFileSend);
        //发送schema描述文件到跨网代理
        if(schemaFile.exists()) {
            ServiceUtil.sendToProxy(schemaFile.getName(), schemaFile.length(), offlineFile.getRegion(), proxyFileSend);
        }
        OfflineFileWarpper wrapper = new OfflineFileWarpper();
        wrapper.setOfflineFile(offlineFile);
        kafkaProducer.sendFile(wrapper);
        //异步调用30s标签接口
        labelTemplate.RefTagByFile(filePath, offlineFile.getIssueName());
        return ResultDto.success("uploading success!",offlineFile);
    }

    private File generateMeta(OfflineFile offlineFile) {
        //生成meta文件
        String metaName = System.currentTimeMillis() + "_" + ServiceUtil.buildMetaName(offlineFile.getFileName());
        String metaPath = uploadPath + metaName;
        //生成schema描述文件
        FileSchema fileSchema = new FileSchema();
        BeanUtils.copyProperties(offlineFile, fileSchema);
        if(StringUtils.hasLength(offlineFile.getAttrs())) {
            Fields fields = new Fields();
            fields.setFields(JSONArray.parseArray(offlineFile.getAttrs(), Field.class));
            fileSchema.setFields(fields);
        }
        ServiceUtil.writeXml(fileSchema, metaPath);
        // 发送schema描述文件到跨网代理
        File schemaFile = new File(metaPath);
        return schemaFile;
    }



    @Override
    public Page<OfflineFile> findFileByFileName(Integer pageNo, Integer pageSize,String name) {
        PageHelper.startPage(pageNo, pageSize);
        Page<OfflineFile> fileByFileName = offlineFileMapper.findFileByFileName(name);
        return fileByFileName;
    }

    @Override
    public List<OfflineFile> selectOffLineFileById(Integer id) {
        List<OfflineFile> offlineFiles = this.baseMapper.selectOffLineFileById(id);
        return offlineFiles;
    }

    @Override
    public OfflineFile selectOfflineFileByName(String fileName) {
        return offlineFileMapper.selectOfflineFileByName(fileName);
    }

}
